use crate::error::{TauriResult, CommandResponse};
use crate::types::{LspServerId, CompletionList, Hover, Location, DocumentSymbol, Position};
use crate::services::lsp::{LspService, LspServerStatus};
use codegraph_lsp::ResourceStats;
use std::collections::HashMap;
use tauri::command;

/// 启动 LSP 服务器
#[command]
pub async fn start_lsp_server(language: String) -> TauriResult<CommandResponse<LspServerId>> {
    log::info!("Starting LSP server for language: {}", language);
    
    match LspService::start_server(&language).await {
        Ok(server_id) => {
            log::info!("LSP server started successfully: {:?}", server_id);
            Ok(CommandResponse::success(server_id))
        }
        Err(e) => {
            log::error!("Failed to start LSP server for {}: {}", language, e);
            Ok(CommandResponse::error(format!("启动 LSP 服务器失败: {}", e)))
        }
    }
}

/// 停止 LSP 服务器
#[command]
pub async fn stop_lsp_server(server_id: LspServerId) -> TauriResult<CommandResponse<String>> {
    log::info!("Stopping LSP server: {:?}", server_id);

    match LspService::stop_server(server_id).await {
        Ok(message) => {
            log::info!("LSP server stopped successfully");
            Ok(CommandResponse::success(message))
        }
        Err(e) => {
            log::error!("Failed to stop LSP server: {}", e);
            Ok(CommandResponse::error(format!("停止 LSP 服务器失败: {}", e)))
        }
    }
}

/// 重启 LSP 服务器
#[command]
pub async fn restart_lsp_server(language: String) -> TauriResult<CommandResponse<LspServerId>> {
    log::info!("Restarting LSP server for language: {}", language);

    match LspService::restart_server(&language).await {
        Ok(server_id) => {
            log::info!("LSP server restarted successfully: {:?}", server_id);
            Ok(CommandResponse::success(server_id))
        }
        Err(e) => {
            log::error!("Failed to restart LSP server for {}: {}", language, e);
            Ok(CommandResponse::error(format!("重启 LSP 服务器失败: {}", e)))
        }
    }
}

/// 获取所有 LSP 服务器状态
#[command]
pub async fn get_all_lsp_servers_status() -> TauriResult<CommandResponse<HashMap<String, LspServerStatus>>> {
    log::debug!("Getting all LSP servers status");

    match LspService::get_all_servers_status().await {
        Ok(status_map) => {
            log::debug!("Retrieved status for {} servers", status_map.len());
            Ok(CommandResponse::success(status_map))
        }
        Err(e) => {
            log::error!("Failed to get LSP servers status: {}", e);
            Ok(CommandResponse::error(format!("获取 LSP 服务器状态失败: {}", e)))
        }
    }
}

/// 获取 LSP 服务器资源统计
#[command]
pub async fn get_lsp_server_stats(language: String) -> TauriResult<CommandResponse<Option<ResourceStats>>> {
    log::debug!("Getting LSP server stats for language: {}", language);

    match LspService::get_server_resource_stats(&language).await {
        Ok(stats) => {
            log::debug!("Retrieved resource stats for {}", language);
            Ok(CommandResponse::success(stats))
        }
        Err(e) => {
            log::error!("Failed to get LSP server stats for {}: {}", language, e);
            Ok(CommandResponse::error(format!("获取 LSP 服务器统计失败: {}", e)))
        }
    }
}

/// 为文件发现合适的 LSP 服务器
#[command]
pub async fn discover_lsp_server_for_file(file_path: String) -> TauriResult<CommandResponse<Option<String>>> {
    log::debug!("Discovering LSP server for file: {}", file_path);

    match LspService::discover_server_for_file(&file_path).await {
        Ok(language) => {
            if let Some(ref lang) = language {
                log::debug!("Discovered LSP server for {}: {}", file_path, lang);
            } else {
                log::debug!("No LSP server found for file: {}", file_path);
            }
            Ok(CommandResponse::success(language))
        }
        Err(e) => {
            log::error!("Failed to discover LSP server for {}: {}", file_path, e);
            Ok(CommandResponse::error(format!("发现 LSP 服务器失败: {}", e)))
        }
    }
}

/// 为文件自动启动 LSP 服务器
#[command]
pub async fn auto_start_lsp_server_for_file(file_path: String) -> TauriResult<CommandResponse<Option<LspServerId>>> {
    log::info!("Auto-starting LSP server for file: {}", file_path);

    match LspService::auto_start_server_for_file(&file_path).await {
        Ok(server_id) => {
            if let Some(ref id) = server_id {
                log::info!("Auto-started LSP server for {}: {:?}", file_path, id);
            } else {
                log::info!("No LSP server available for file: {}", file_path);
            }
            Ok(CommandResponse::success(server_id))
        }
        Err(e) => {
            log::error!("Failed to auto-start LSP server for {}: {}", file_path, e);
            Ok(CommandResponse::error(format!("自动启动 LSP 服务器失败: {}", e)))
        }
    }
}

/// LSP 自动完成
#[command]
pub async fn lsp_completion(
    file_path: String,
    position: Position,
    language: String,
) -> TauriResult<CommandResponse<CompletionList>> {
    log::debug!("LSP completion request for {} at {:?}", file_path, position);
    
    match LspService::get_completion(&file_path, position, &language).await {
        Ok(completion_list) => {
            log::debug!("LSP completion returned {} items", completion_list.items.len());
            Ok(CommandResponse::success(completion_list))
        }
        Err(e) => {
            log::error!("LSP completion failed: {}", e);
            Ok(CommandResponse::error(format!("自动完成失败: {}", e)))
        }
    }
}

/// LSP 悬停提示
#[command]
pub async fn lsp_hover(
    file_path: String,
    position: Position,
    language: String,
) -> TauriResult<CommandResponse<Option<Hover>>> {
    log::debug!("LSP hover request for {} at {:?}", file_path, position);
    
    match LspService::get_hover(&file_path, position, &language).await {
        Ok(hover) => {
            log::debug!("LSP hover completed");
            Ok(CommandResponse::success(hover))
        }
        Err(e) => {
            log::error!("LSP hover failed: {}", e);
            Ok(CommandResponse::error(format!("悬停提示失败: {}", e)))
        }
    }
}

/// LSP 定义跳转
#[command]
pub async fn lsp_definition(
    file_path: String,
    position: Position,
    language: String,
) -> TauriResult<CommandResponse<Vec<Location>>> {
    log::debug!("LSP definition request for {} at {:?}", file_path, position);
    
    match LspService::get_definition(&file_path, position, &language).await {
        Ok(locations) => {
            log::debug!("LSP definition returned {} locations", locations.len());
            Ok(CommandResponse::success(locations))
        }
        Err(e) => {
            log::error!("LSP definition failed: {}", e);
            Ok(CommandResponse::error(format!("定义跳转失败: {}", e)))
        }
    }
}

/// LSP 引用查找
#[command]
pub async fn lsp_references(
    file_path: String,
    position: Position,
    language: String,
    include_declaration: bool,
) -> TauriResult<CommandResponse<Vec<Location>>> {
    log::debug!("LSP references request for {} at {:?}", file_path, position);
    
    match LspService::get_references(&file_path, position, &language, include_declaration).await {
        Ok(locations) => {
            log::debug!("LSP references returned {} locations", locations.len());
            Ok(CommandResponse::success(locations))
        }
        Err(e) => {
            log::error!("LSP references failed: {}", e);
            Ok(CommandResponse::error(format!("引用查找失败: {}", e)))
        }
    }
}

/// LSP 符号查询
#[command]
pub async fn lsp_symbols(
    file_path: String,
    language: String,
) -> TauriResult<CommandResponse<Vec<DocumentSymbol>>> {
    log::debug!("LSP symbols request for {}", file_path);
    
    match LspService::get_document_symbols(&file_path, &language).await {
        Ok(symbols) => {
            log::debug!("LSP symbols returned {} symbols", symbols.len());
            Ok(CommandResponse::success(symbols))
        }
        Err(e) => {
            log::error!("LSP symbols failed: {}", e);
            Ok(CommandResponse::error(format!("符号查询失败: {}", e)))
        }
    }
}

/// LSP 工作区符号查询
#[command]
pub async fn lsp_workspace_symbols(
    query: String,
    language: String,
) -> TauriResult<CommandResponse<Vec<DocumentSymbol>>> {
    log::debug!("LSP workspace symbols request with query: {}", query);
    
    match LspService::get_workspace_symbols(&query, &language).await {
        Ok(symbols) => {
            log::debug!("LSP workspace symbols returned {} symbols", symbols.len());
            Ok(CommandResponse::success(symbols))
        }
        Err(e) => {
            log::error!("LSP workspace symbols failed: {}", e);
            Ok(CommandResponse::error(format!("工作区符号查询失败: {}", e)))
        }
    }
}

/// LSP 格式化文档
#[command]
pub async fn lsp_format_document(
    file_path: String,
    language: String,
) -> TauriResult<CommandResponse<String>> {
    log::debug!("LSP format document request for {}", file_path);
    
    match LspService::format_document(&file_path, &language).await {
        Ok(formatted_content) => {
            log::debug!("LSP document formatting completed");
            Ok(CommandResponse::success(formatted_content))
        }
        Err(e) => {
            log::error!("LSP document formatting failed: {}", e);
            Ok(CommandResponse::error(format!("文档格式化失败: {}", e)))
        }
    }
}

/// LSP 诊断信息
#[command]
pub async fn lsp_diagnostics(
    file_path: String,
    language: String,
) -> TauriResult<CommandResponse<serde_json::Value>> {
    log::debug!("LSP diagnostics request for {}", file_path);
    
    match LspService::get_diagnostics(&file_path, &language).await {
        Ok(diagnostics) => {
            log::debug!("LSP diagnostics completed");
            Ok(CommandResponse::success(diagnostics))
        }
        Err(e) => {
            log::error!("LSP diagnostics failed: {}", e);
            Ok(CommandResponse::error(format!("诊断信息获取失败: {}", e)))
        }
    }
}

/// 获取 LSP 服务器状态
#[command]
pub async fn get_lsp_server_status() -> TauriResult<CommandResponse<serde_json::Value>> {
    log::debug!("Getting LSP server status");
    
    match LspService::get_server_status().await {
        Ok(status) => {
            log::debug!("LSP server status retrieved");
            Ok(CommandResponse::success(status))
        }
        Err(e) => {
            log::error!("Failed to get LSP server status: {}", e);
            Ok(CommandResponse::error(format!("获取 LSP 服务器状态失败: {}", e)))
        }
    }
}


